/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = wtc_typedbuffer.c                                  */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/25 by songbb                               */
/*******************************************************************/

#include "conntrack.h"
#include "frct_comm.h"
#include "frreport_comm.h"

#include "../wtc_core.h"
#include "../wtc_comm.h"
#include "wtc_typedbuffer.h"
#include "wtc_typed_string.h"
#include "wtc_wsrpcrq.h"
#include "wtc_typed_fml32.h"
#include "wtc_typed_fml.h"
#include "wtc_tpinit.h"
#include "wtc_typed_xml.h"
#include "wtc_typed_tgiop.h"
#include "wtc_typed_xoctet.h"
#include "wtc_typed_mbstring.h"

int wtc_add_typedbuffer(Conntrack *p_st_conn
                        , char *p_type
                        , char *p_subtype
                        , unsigned int ui_fld
                        , L7_wtc_packet *p_st_wtc_packet
                        , unsigned int ui_skip_len
                        , Frreport_body_data *p_st_body)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_wtc_private *p_st_session_private = (L7session_wtc_private *) frct_get_session_private(p_st_session);
    L7_wtc_stmt *p_st_wtc_stmt = p_st_session_private->p_st_wtc_stmt;
    char *p_tmp = NULL;
    char *p_field_name = NULL;
    int i_field_name_len = 0;

    if (p_type == NULL)
    {
        if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) ui_skip_len) != FR_SUCC)
            goto error;
        return FR_SUCC;
    }

    if (strcmp(p_type, APM_WTC_VIEW_STRING) == 0 ||
        strcmp(p_type, APM_WTC_VIEW32_STRING) == 0 ||
        strcmp(p_type, APM_WTC_X_COMMON_STRING) == 0 ||
        strcmp(p_type, APM_WTC_X_C_TYPE_STRING) == 0 ||
        strcmp(p_type, APM_WTC_CARRAY_STRING) == 0)
    {
        if ((p_tmp = (char *) frmalloc(ui_skip_len * sizeof(char))) == NULL)
        {
            WTC_MALLOCK_ERR;
            goto error;
        }
        if (bytebuff_get_bytes(p_st_wtc_packet->p_st_packet, p_tmp, ui_skip_len) != FR_SUCC)
            goto error;

        i_field_name_len = strlen(p_st_wtc_packet->i_is_req == FR_YES ? APM_DTS_REPORT_REQ_ARG_DATA : APM_DTS_REPORT_RESP_ARG_DATA) + 16;
        if ((p_field_name = (char *) frmalloc(i_field_name_len * sizeof(char))) == NULL)
        {
            WTC_MALLOCK_ERR;
            goto error;
        }
        snprintf(p_field_name, (size_t) i_field_name_len, "%s%d", p_st_wtc_packet->i_is_req == FR_YES ? APM_DTS_REPORT_REQ_ARG_DATA
                                                                                                      : APM_DTS_REPORT_RESP_ARG_DATA, ui_fld);

        if (p_st_body != NULL)
        {
            if (frreport_body_l7_add_bin(p_st_body, p_field_name, p_tmp, ui_skip_len) != FR_SUCC)
                goto error;
            p_st_wtc_stmt->ui_arg_count++;
        }

        wtc_free((void **) &p_field_name);
    }
    else
    {
        if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) ui_skip_len) != FR_SUCC)
            goto error;
    }

    wtc_free((void **) &p_tmp);
    return FR_SUCC;
error:
    wtc_free((void **) &p_field_name);
    wtc_free((void **) &p_tmp);
    return FR_FAIL;
}

typedbufferfunc wtc_create_view_instance(char *p_subtype)
{
    if (p_subtype == NULL)
        return NULL;
//  TODO:  return new ViewHelper().newViewInstance(subtype);
    return NULL;
}

typedbufferfunc wtc_create_typedbuffer_by_type(char *p_type
                                            , char *p_subtype)
{
    if (p_type == NULL)
        return NULL;

    if (strcmp(p_type, APM_WTC_STRING_STRING) == 0)
        return (typedbufferfunc) wtc_typed_string_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_CARRAY_STRING) == 0)
        return NULL;
    else if (strcmp(p_type, APM_WTC_FML_STRING) == 0)
        return (typedbufferfunc) wtc_typed_fml_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_FML32_STRING) == 0)
        return (typedbufferfunc) wtc_typed_fml32_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_VIEW_STRING) == 0 || strcmp(p_type, APM_WTC_VIEW32_STRING) == 0)
        return wtc_create_view_instance(p_subtype);
    else if (strcmp(p_type, APM_WTC_TPINITTYPE_STRING) == 0)
        return (typedbufferfunc) wtc_tpinit_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_WSRPCRQ_STRING) == 0)
        return (typedbufferfunc) wtc_wsrpcrq_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_XML_STRING) == 0)
        return (typedbufferfunc) wtc_typed_xml_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_TGIOP_STRING) == 0)
        return (typedbufferfunc) wtc_typed_tgiop_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_X_OCTET_STRING) == 0)
        return (typedbufferfunc) wtc_typed_xoctet_tmpostrecv;
    else if (strcmp(p_type, APM_WTC_X_COMMON_STRING) == 0 || strcmp(p_type, APM_WTC_X_C_TYPE_STRING) == 0)
        return wtc_create_view_instance(p_subtype);
    else if (strcmp(p_type, APM_WTC_MBSTRING_STRING) == 0)
        return (typedbufferfunc) wtc_typed_mbstring_tmpostrecv;

    return NULL;
}

typedbufferfunc wtc_create_typedbuffer(int i_hint_index
                                    , char *p_type
                                    , char *p_subtype)
{
    if (i_hint_index < 0 || p_type == NULL)
        return NULL;

    switch (i_hint_index)
    {
        case APM_WTC_WSRPCRQ_HINT:
            if (strcmp(p_type, APM_WTC_WSRPCRQ_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_wsrpcrq_tmpostrecv;
        case APM_WTC_CARRAY_HINT:
            if (strcmp(p_type, APM_WTC_CARRAY_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return NULL;
        case APM_WTC_STRING_HINT:
            if (strcmp(p_type, APM_WTC_STRING_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_string_tmpostrecv;
        case APM_WTC_FML_HINT:
            if (strcmp(p_type, APM_WTC_FML_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_fml_tmpostrecv;
        case APM_WTC_FML32_HINT:
            if (strcmp(p_type, APM_WTC_FML32_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_fml32_tmpostrecv;
        case APM_WTC_VIEW_HINT:
            if (strcmp(p_type, APM_WTC_VIEW_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return wtc_create_view_instance(p_subtype);
        case APM_WTC_VIEW32_HINT:
            if (strcmp(p_type, APM_WTC_VIEW32_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return wtc_create_view_instance(p_subtype);
        case APM_WTC_X_COMMON_HINT:
            if (strcmp(p_type, APM_WTC_X_COMMON_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return wtc_create_view_instance(p_subtype);
        case APM_WTC_X_C_TYPE_HINT:
            if (strcmp(p_type, APM_WTC_X_C_TYPE_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return wtc_create_view_instance(p_subtype);
        case APM_WTC_XML_HINT:
            if (strcmp(p_type, APM_WTC_XML_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_xml_tmpostrecv;
        case APM_WTC_TGIOP_HINT:
            if (strcmp(p_type, APM_WTC_TGIOP_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_tgiop_tmpostrecv;
        case APM_WTC_X_OCTET_HINT:
            if (strcmp(p_type, APM_WTC_X_OCTET_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_xoctet_tmpostrecv;
        case APM_WTC_MBSTRING_HINT:
            if (strcmp(p_type, APM_WTC_MBSTRING_STRING) != 0)
                return wtc_create_typedbuffer_by_type(p_type, p_subtype);
            return (typedbufferfunc) wtc_typed_mbstring_tmpostrecv;
        default:
            return wtc_create_typedbuffer_by_type(p_type, p_subtype);
    }
}

//////////////////////// for analyze direction

typedbufferfunc_fad wtc_create_view_instance_fad(char *p_subtype)
{
    if (p_subtype == NULL)
        return NULL;
    return NULL;
}

typedbufferfunc_fad wtc_create_typedbuffer_by_type_fad(char *p_type
                                                    , char *p_subtype)
{
    if (p_type == NULL)
        return NULL;

    if (strcmp(p_type, APM_WTC_STRING_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_string_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_CARRAY_STRING) == 0)
        return NULL;
    else if (strcmp(p_type, APM_WTC_FML_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_fml_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_FML32_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_fml32_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_VIEW_STRING) == 0 || strcmp(p_type, APM_WTC_VIEW32_STRING) == 0)
        return wtc_create_view_instance_fad(p_subtype);
    else if (strcmp(p_type, APM_WTC_TPINITTYPE_STRING) == 0)
        return (typedbufferfunc_fad) wtc_tpinit_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_WSRPCRQ_STRING) == 0)
        return (typedbufferfunc_fad) wtc_wsrpcrq_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_XML_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_xml_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_TGIOP_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_tgiop_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_X_OCTET_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_xoctet_tmpostrecv_fad;
    else if (strcmp(p_type, APM_WTC_X_COMMON_STRING) == 0 || strcmp(p_type, APM_WTC_X_C_TYPE_STRING) == 0)
        return wtc_create_view_instance_fad(p_subtype);
    else if (strcmp(p_type, APM_WTC_MBSTRING_STRING) == 0)
        return (typedbufferfunc_fad) wtc_typed_mbstring_tmpostrecv_fad;

    return NULL;
}

typedbufferfunc_fad wtc_create_typedbuffer_fad(int i_hint_index
                                                , char *p_type
                                                , char *p_subtype)
{
    if (i_hint_index < 0 || p_type == NULL)
        return NULL;

    switch (i_hint_index)
    {
        case APM_WTC_WSRPCRQ_HINT:
            if (strcmp(p_type, APM_WTC_WSRPCRQ_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_wsrpcrq_tmpostrecv_fad;
        case APM_WTC_CARRAY_HINT:
            if (strcmp(p_type, APM_WTC_CARRAY_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return NULL;
        case APM_WTC_STRING_HINT:
            if (strcmp(p_type, APM_WTC_STRING_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_string_tmpostrecv_fad;
        case APM_WTC_FML_HINT:
            if (strcmp(p_type, APM_WTC_FML_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_fml_tmpostrecv_fad;
        case APM_WTC_FML32_HINT:
            if (strcmp(p_type, APM_WTC_FML32_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_fml32_tmpostrecv_fad;
        case APM_WTC_VIEW_HINT:
            if (strcmp(p_type, APM_WTC_VIEW_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return wtc_create_view_instance_fad(p_subtype);
        case APM_WTC_VIEW32_HINT:
            if (strcmp(p_type, APM_WTC_VIEW32_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return wtc_create_view_instance_fad(p_subtype);
        case APM_WTC_X_COMMON_HINT:
            if (strcmp(p_type, APM_WTC_X_COMMON_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return wtc_create_view_instance_fad(p_subtype);
        case APM_WTC_X_C_TYPE_HINT:
            if (strcmp(p_type, APM_WTC_X_C_TYPE_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return wtc_create_view_instance_fad(p_subtype);
        case APM_WTC_XML_HINT:
            if (strcmp(p_type, APM_WTC_XML_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_xml_tmpostrecv_fad;
        case APM_WTC_TGIOP_HINT:
            if (strcmp(p_type, APM_WTC_TGIOP_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_tgiop_tmpostrecv_fad;
        case APM_WTC_X_OCTET_HINT:
            if (strcmp(p_type, APM_WTC_X_OCTET_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_xoctet_tmpostrecv_fad;
        case APM_WTC_MBSTRING_HINT:
            if (strcmp(p_type, APM_WTC_MBSTRING_STRING) != 0)
                return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
            return (typedbufferfunc_fad) wtc_typed_mbstring_tmpostrecv_fad;
        default:
            return wtc_create_typedbuffer_by_type_fad(p_type, p_subtype);
    }
}
